package com.vertx.core.annotation.inject.explain;

import com.vertx.core.annotation.base.FieldAnnotationExplain;
import com.vertx.core.annotation.data.Query;
import com.vertx.core.annotation.inject.Autowired;
import com.vertx.core.annotation.inject.Component;
import com.vertx.core.beam.AbstractBeanFactory;
import com.vertx.core.beam.BeanContainer;
import com.vertx.core.exception.AnnotationExplainUnMatchedException;
import com.vertx.core.exception.FieldClassAnnotationNoSuchException;
import com.vertx.core.exception.TargetRegisterClassNoSuchException;
import com.vertx.core.utils.ClassUtil;
import org.apache.log4j.Logger;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.List;

/**
 * 描述:
 * 创建人:hzw
 * 创建时间: 2018/4/17 16:17
 **/
public class AutowiredExplain implements FieldAnnotationExplain {

    private static final Logger logger = Logger.getLogger(AutowiredExplain.class);

    @Override
    public Annotation getExplainClass() {
        return () -> Autowired.class;
    }

    @Override
    public void handler(BeanContainer beanContainer, Field field, Annotation annotation, AbstractBeanFactory beanFactory, Object[] params) throws Exception {
        String name;
        if (annotation instanceof Autowired) {
            name = ((Autowired) annotation).name();
        } else {
            logger.error("注解解释器不匹配");
            throw new AnnotationExplainUnMatchedException("注解解释器不匹配");
        }

        //如果字段使用了@Autowired注解，但是字段的类未使用@Component,@Query注解 就抛出异常
        if(field.getType().isInterface()){//如果字段是接口类型
            String[] pack=(String[])params[0];
            //扫描得到路径
            List<Class> classes=ClassUtil.getAllClassByInterface(field.getType(),pack[0]);
            for (Class x:classes){
                Annotation fieldClassAnnotation = x.getAnnotation(Component.class);
                Annotation fieldClassQuery=x.getAnnotation(Query.class);
                if (null!=fieldClassAnnotation||null!=fieldClassQuery) {
                    Object value;
                    String beanName;
                    if (name.length() > 0) {
                        //优先使用注解的name属性值去获取对象
                        beanName = name;
                        value = beanFactory.getBean(beanName);
                    } else {
                        beanName = beanFactory.getSimpleClassName(x);
                        value = beanFactory.getBean(beanName);
                    }
                    if (value != null) {
                        field.setAccessible(true);
                        field.set(beanContainer.getBean(), value);
                    } else {
                        throw new TargetRegisterClassNoSuchException("上下文找不到已经注册的：" + beanName);
                    }
                }else {
                    throw new FieldClassAnnotationNoSuchException(field.getName() + "未注册 也未声明 @Component");
                }
            }
        }else{
            Annotation fieldClassAnnotation = field.getType().getAnnotation(Component.class);
            Annotation fieldClassQuery=field.getType().getAnnotation(Query.class);
            if (null!=fieldClassAnnotation||null!=fieldClassQuery) {
                Object value;
                String beanName;
                if (name.length() > 0) {
                    //优先使用注解的name属性值去获取对象
                    beanName = name;
                    value = beanFactory.getBean(beanName);
                } else {
                    beanName = beanFactory.getSimpleClassName(field.getType());
                    value = beanFactory.getBean(beanName);
                }
                if (value != null) {
                    field.setAccessible(true);
                    field.set(beanContainer.getBean(), value);
                } else {
                    throw new TargetRegisterClassNoSuchException("上下文找不到已经注册的：" + beanName);
                }
            } else {
                throw new FieldClassAnnotationNoSuchException(field.getName() + "未注册 也未声明 @Component");
            }
        }
    }
}
